﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

using GolfSigma.Inventory;
using GolfSigma.Inventory.Model;

namespace GolfSigma.Inventory.Console
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create a new instance of our client
            var client = new InventoryClient(
                "32633c3ea2d5450095414169786c308e",
                "V7XSVunann6Wa7HAU8IfEKaNGOAE2EcNOV10xaojRfjnAQUUOm4Pdr/RkXvLFu3czslylpEWrjNviD3PasFytg",
                new InventoryConfig()
                {
                    MaxErrorRetry = 0,
                    //ServiceURL = "http://ipv4.fiddler:54657",
                    ServiceURL = "http://inv.golfsigmaws.com:54657",
                    ProxyHost = "localhost",
                    ProxyPort = 8888,
                    UserAgent = "GolfSigma.Inventory.Console",
                    SetForwardedFor = false
                });

            //byte[] secretkey = new Byte[64];
            //RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            //rng.GetBytes(secretkey);
            //var key = Convert.ToBase64String(secretkey);

            // Try and get a teetime
            //var result = client.GetTeeTime(
            //    new GetTeeTimeRequest(
            //        new Guid("e3c0570fe3304fe29eb94befed8f59d0")
            //        )
            //    );

            // Try and get a search
            //var result = client.GetSearch(
            //    new GetSearchRequest(
            //        new Guid("9e5c514a833b45c6ba3689437db32613")
            //        )
            //    );

            // Try and get inventory by searchId
            //var result = client.GetInventory(
            //    new GetInventoryRequest(
            //        new Guid("5531441c1dc74511b637b4c510602170")
            //        )
            //    );

            // Try and get inventory in a single call by creating a search at the same time
            //var result = client.GetInventory(
            //        new PutSearchRequest()
            //        {
            //            Search = new Search()
            //            {
            //                ExternalId = "invClientLibrary",
            //                Date = DateTime.Now.AddDays(2).Date,
            //                MaxDaysOut = 1,
            //                Players = PlayerEnum.All,
            //                SearchType = SearchTypeEnum.SingleDay,
            //                TimeOfDay = new TimeSpan(9, 30, 0),
            //                Attributes = new List<TeeTimeAttributeEnum>()
            //                {
            //                    TeeTimeAttributeEnum.Holes18
            //                },
            //                CourseIds = new List<Guid>()
            //                {
            //                    new Guid("765bb849-4766-452a-aa0b-49a933dfb7bb")
            //                },
            //                Filters = new List<SearchFilter>()
            //                {
            //                    new SearchFilter(new Guid("90d280e6-a8e2-428a-992f-cb47b9c799d3"), "Interval", "30")
            //                }
            //            }
            //        }
            //    );

            // Try and get similar tee-times
            //var result = client.GetSimilarTeeTimes(
            //    new GetSimilarTeeTimeRequest(
            //        new Guid("f9189ef2feaf4a68a2a4fbc7c43fbf84")
            //        )
            //    );

            // Create a search
            //var result = client.PutSearch(
            //    new PutSearchRequest()
            //    {
            //        Search = new Search()
            //        {
            //            ExternalId = "invClientLibrary",
            //            Date = DateTime.Now.AddDays(7),
            //            MaxDaysOut = 1,
            //            Players = PlayerEnum.Threesome,
            //            SearchType = SearchTypeEnum.SingleDay,
            //            TimeOfDay = new TimeSpan(9, 30, 0),
            //            Attributes = new List<TeeTimeAttributeEnum>()
            //            {
            //                TeeTimeAttributeEnum.Holes18,
            //                TeeTimeAttributeEnum.MembersOnly
            //            },
            //            Filters = new List<SearchFilter>()
            //            {
            //                new SearchFilter(new Guid("22816dc4-538e-412e-8594-f46150e6520c"), "MinPrice", "20")
            //            },
            //            CourseIds = new List<ulong>()
            //            {
            //                8731
            //            }
            //        }
            //    });

            // Batch put multiple tee times
            var start = DateTime.Now.Ticks;
            var teeTimes = new List<Model.TeeTime>();
            var random = new Random();
            for (int d = 2; d <= 2; d++)
            {
                for (int a = 0; a < 15; a++)
                {
                    for (int i = 0; i < 200; i++)
                    {
                        teeTimes.Add(
                            new TeeTime()
                            {
                                CourseId = GetRandomCourseId(random),
                                MiscData = i.ToString(),
                                Players = GetRandomPlayers(random),
                                //Players = PlayerEnum.Twosome,
                                Time = GetRandomDate(random, d),
                                TotalPricePerPlayer = GetRandomPrice(random),
                                WebSiteId = GetRandomWebsite(random),
                                Attributes = new List<TeeTimeAttributeEnum>()
                            {
                                TeeTimeAttributeEnum.Holes18    
                            },
                                Fees = new Dictionary<FeeEnum, float>()
                            {
                                { FeeEnum.Green, GetRandomPrice(random) },
                                { FeeEnum.Cart, GetRandomPrice(random) }
                            }
                            });
                    }
                    client.BatchPutTeeTimes(
                        new BatchPutTeeTimesRequest(teeTimes)
                        );
                    teeTimes.Clear();
                }
            }

            var end = DateTime.Now.Ticks;
            var timespan = new TimeSpan(end - start);

            // Put a single tee times
            //var random = new Random();
            //var result = client.PutTeeTime(
            //    new PutTeeTimeRequest()
            //    {
            //        TeeTime = new TeeTime()
            //        {
            //            CourseId = 8731,
            //            ApplicationData = "feeTest",
            //            Players = PlayerEnum.All,
            //            Time = GetRandomDate(random),
            //            TotalPricePerPlayer = GetRandomPrice(random),
            //            WebSiteId = 14,
            //            Fees = new Dictionary<FeeEnum, float>()
            //            {
            //                { FeeEnum.Green, 45F },
            //                { FeeEnum.Cart, 10F }
            //            }
            //        }
            //    });

            // Create a reservation
            //var result = client.PutReservation(
            //    new PutReservationRequest()
            //    {
            //        Reservation = new Reservation()
            //        {
            //            ExternalId = "shaunWasHere",
            //            SearchId = 2,
            //            TeeTimeId = 201,
            //        }
            //    });

            // Get an existing reservation
            //var result = client.GetReservation(
            //    new GetReservationRequest()
            //    {
            //        ReservationId = new Guid("66dacf5c2cb04d4683317f3a3aae5fcc")
            //    });
        }

        static DateTime GetRandomDate(Random random, int daysOut)
        {
            var randomSeconds = random.Next(0, 39600);

            DateTime minDate = DateTime.Now.AddDays(daysOut).Date.AddHours(6);
            var result = minDate.AddSeconds(randomSeconds);

            return result.AddSeconds(-result.Second);
        }

        static float GetRandomPrice(Random random)
        {
            var rnd = new Random();
            var randomAddition = random.Next(0, 10000);

            float minPrice = 10;

            return minPrice + (randomAddition / 100F);
        }

        static PlayerEnum GetRandomPlayers(Random random)
        {
            var rnd = new Random();
            var randomAddition = random.Next(1, 4);

            switch (randomAddition)
            {
                case 1: return PlayerEnum.Single;
                case 2: return PlayerEnum.Twosome | PlayerEnum.Single;
                case 3: return PlayerEnum.Threesome | PlayerEnum.Twosome;
                case 4:
                default: return PlayerEnum.All;
            }
        }

        static UInt64 GetRandomCourseId(Random random)
        {
            var stringCourseIds = "427,443,474,484,491,515,516,530,554,558,562,566,8731,8732,581,619,631,654,684,698,714,8733,8734,8735,436,9748,9749,444,446,450,10148,456,9744,9745,9723,9724,466,470,477,478,496,502,504,505,514,533,537,538,548,551,556,559,560,563,564,569,570,572,587,591,594,595,600,601,633,634,642,644,649,665,670,672,676,677,679,683,10383,10384,689,700,702,708,10238,10239,9746,9747,713,9721,9722,722,724,728,729,733,9725,9726,9727,9728,9750,9751,9753,9754,9755,10240,10386";
            var courseIds = new List<UInt64>();
            foreach (var item in stringCourseIds.Split(new char[] { ',' }))
            {
                UInt64 courseId;
                if (UInt64.TryParse(item, out courseId))
                    courseIds.Add(courseId);
            }

            var randomCourseIndex = random.Next(0, courseIds.Count - 1);
            return courseIds[randomCourseIndex];
        }

        static UInt32 GetRandomWebsite(Random random)
        {
            var webSiteIds = new UInt32[] { 9, 14, 11 };
            var randomAddition = random.Next(0, webSiteIds.Length - 1);

            return webSiteIds[randomAddition];
        }
    }
}
